#!/usr/bin/env python2

import os
import errno
import platform

from utils import Exp, _dwarn, _derror, _exec_pipe, _exec_pipe1
from Iface import RAID_Iface
from PluginManager import PluginManager

class RAID:
    def __init__(self, disktool):
        PluginManager.SetPluginPath(os.path.join(os.path.dirname(__file__), 'Plugins'))
        PluginManager.LoadAllPlugin()
        self.disktool = disktool

    def get_disk_raidcard(self, disk):
        new_raid_disk = self.disk_list()
        for raid in new_raid_disk:
            new_raid = new_raid_disk[raid]
            for adp, disks in new_raid.iteritems():
                if disk in disks.keys():
                    return raid

    def raid_add(self, dev, force):
        raidcard = self.get_disk_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.add_raid0(dev, force)
        else:
            return None

    def raid_del(self, dev, force):
        raidcard = self.disktool.get_dev_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.del_raid0(dev, force)
        else:
            return None

    def raid_import(self):
        raidcards = self.disktool.get_all_raid()
        for raid in raidcards:
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
            if plugin:
                plugin.import_raid_foreign()

    def raid_flush(self):
        raidcards = self.disktool.get_all_raid()
        for raid in raidcards:
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
            if plugin:
                plugin.raid_cache_flush()

    def raid_cache(self, switch, devs, cacheconf, cache):
        if switch == 'show':
            for dev in devs:
                raidcard = self.disktool.get_dev_raidcard(dev)
                plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
                if plugin:
                    raid_cache = plugin.get_raid_cache(dev)
                    print dev, ":", raid_cache
        elif switch == 'set' and cache:
            for dev in devs:
                raidcard = self.disktool.get_dev_raidcard(dev)
                plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
                if plugin:
                    plugin.set_raid_policy(dev, cache)
        elif switch == 'set':
            self.raid_check(devs, cacheconf);
            for dev in devs:
                raidcard = self.disktool.get_dev_raidcard(dev)
                plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
                if plugin:
                    plugin.set_raid_ratio(dev)

    def raid_miss(self):
        raidcards = self.disktool.get_all_raid()
        for raid in raidcards:
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
            if plugin:
                plugin.del_raid_missing()

    def raid_light(self, switch, devs):
        if switch == 'list':
            raidcards = self.disktool.get_all_raid()
            for raid in raidcards:
                plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
                if plugin:
                    disk_light = plugin.get_light_flash()
                    if len(disk_light) == 0:
                        print "No disk light is starting in", raid
                    else:
                        print disk_light
        for dev in devs:
            raidcard = self.disktool.get_dev_raidcard(dev)
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
            if plugin:
                plugin.set_light_flash(switch, dev)

    def raid_check(self, devs, cacheconf, force=False, setcache=True):
        if len(cacheconf) == 0:
            return

        cache_devs = {}
        for dev in devs:
            raidcard = self.disktool.get_dev_raidcard(dev)
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
            if plugin:
                check_cache = plugin.check_raid_cache(dev, cacheconf, setcache)
                if len(check_cache) == 0:
                    continue
                else:
                    cache_devs[dev] = check_cache

        if not setcache:
            return cache_devs

        for dev in cache_devs:
            raidcard = self.disktool.get_dev_raidcard(dev)
            try:
                plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
                if plugin:
                    plugin.set_raid_cache(dev, cache_devs[dev])
            except Exp, e:
                if not force:
                    raise Exp(e.errno, "set raid %s cache faile:%s" %(dev, e.err))
                else:
                    _dwarn("set raid %s cache faile, %s" %(dev, e.err))

    def raid_info(self, dev):
        raidcard = self.disktool.get_dev_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.get_dev_info(dev)
        else:
            return None

    def dev_info(self, dev):
        dev_info = self.raid_info(dev)
        raidcard = self.disktool.get_dev_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.get_disk_info(dev_info['disk'][0])
        else:
            return None

    def disk_info(self, dev):
        raidcard = dev.split(':')[1]
        disk = dev.split(':')[2]
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.get_disk_info(disk)
        else:
            return None

    def disk_list(self):
        disks = {}
        raidcards = self.disktool.get_all_raid()
        for raid in raidcards:
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
            if plugin:
                disks[raid] = plugin.get_new_disk()

        return disks

    def disk_model(self, dev):
        raidcard = self.disktool.get_dev_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.get_dev_device_model(dev)
        else:
            return ''

    def disk_rotation(self, dev):
        raidcard = self.disktool.get_dev_raidcard(dev)
        plugin = RAID_Iface.GetPluginObject("%s.%s" % (raidcard, raidcard))
        if plugin:
            return plugin.get_disk_rotation(dev)
        else:
            return None

    def raid_ldpdinfo(self):
        disks = {}
        raidcards = self.disktool.get_all_raid()
        for raid in raidcards:
            plugin = RAID_Iface.GetPluginObject("%s.%s" % (raid, raid))
            if plugin:
                disks[raid] = plugin.get_all_ldpdinfo()

        return disks
